<template>
  <div w-full px-4 flex flex-col py-4>
    <div class="flex justify-between">
      <div pl-4 text-xl font-bold>自建类目</div>
      <a-button type="primary" @click="save" :disabled="saveDsiable">
        保存
      </a-button>
    </div>
    <Nav
      my-4
      :category-name="categoryName"
      :category-code="categoryCode"
      :category-nav="categoryPath"
    ></Nav>
    <div
      block
      w-full
      gap-4
      grid
      grid-cols-2
      flex-1
      overflow-y-hidden
      ref="rootRef"
    >
      <div>
        <div mb-4>
          <a-space>
            <a-button type="primary" @click="addCondition"> 新建条件 </a-button>
            <a-button type="primary" @click="showConditionBatch"
              >批量添加</a-button
            >
            <a-button
              danger
              :disabled="!conditionSelects.length"
              @click="batchRemove"
            >
              批量删除
            </a-button>
          </a-space>
        </div>
        <a-table
          :columns="conditionColumns"
          :data-source="conditionData"
          :pagination="false"
          :scroll="{ y: height - 90 }"
          row-key="alias_name"
          :row-selection="{
            onChange: changeConditionSelect,
          }"
          :custom-row="customRow"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.dataIndex == 'alias_name'">
              <a-input
                :maxlength="20"
                ref="inputRef"
                v-model:value.trim="editValue"
                v-if="record.isEdit"
                placeholder="请输入条件名称"
                @blur="saveCondition(record as ConditionItem)"
                @press-enter="inputRef?.blur"
              ></a-input>
              <span v-else>
                <CheckCircleOutlined
                  text-success
                  v-if="optionData[record.alias_name]?.length"
                />
                {{ record.alias_name }}
              </span>
            </template>

            <template v-if="column.dataIndex == 'action'">
              <a-button
                type="link"
                @click="changeActive(record as ConditionItem)"
              >
                编辑选项
              </a-button>

              <a-button
                type="link"
                @click="editConddtion(record as ConditionItem)"
              >
                编辑
              </a-button>

              <a-button
                type="link"
                @click="removeCondition(record as ConditionItem)"
              >
                删除
              </a-button>
            </template>
          </template>
        </a-table>
      </div>

      <div>
        <div mb-4>
          <a-space>
            <a-button
              type="primary"
              :disabled="!activeCondition"
              @click="addOption"
            >
              新建选项
            </a-button>

            <a-button
              type="primary"
              @click="batchOptionAdd"
              :disabled="!activeCondition"
            >
              批量添加
            </a-button>

            <a-button
              danger
              :disabled="!optionSelects.length"
              @click="batchRemoveOptions"
            >
              批量删除
            </a-button>
          </a-space>
        </div>
        <a-table
          row-key="alias_name"
          v-if="activeCondition"
          :columns="optionsColumns"
          :data-source="optionData[activeCondition.alias_name!]"
          :pagination="false"
          :scroll="{ y: height - 90 }"
          :row-selection="{
            onChange: changeOptionSelect,
          }"
          :customRow="optionCustomRow(activeCondition.alias_name!).customRow"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.dataIndex == 'alias_name'">
              <a-input
                :maxlength="20"
                v-if="record.isEdit"
                ref="inputRef"
                v-model:value.trim="editValue"
                placeholder="请输入选项名称"
                @blur="saveOption(record as OptionItem)"
                @press-enter="inputRef?.blur"
              ></a-input>

              <span v-else>{{ record.alias_name }}</span>
            </template>

            <template v-if="column.dataIndex == 'icon'">
              <Upload v-model="(record as OptionItem).image_url" />
            </template>

            <template v-if="column.dataIndex == 'action'">
              <a-button type="link" @click="editOption(record as OptionItem)">
                编辑
              </a-button>
              <a-button type="link" @click="removeOption(record as OptionItem)">
                删除
              </a-button>
            </template>
          </template>
        </a-table>

        <a-empty v-else>
          <template #description> 请先在左侧点击编辑选项 </template>
        </a-empty>
      </div>
    </div>
    <batch-add ref="batchRef"></batch-add>
  </div>
</template>

<script lang="ts" setup>
import { Category } from '@/types/category';
import Nav from './Selection/Nav.vue';
import { ConditionOption, MatchData } from './Selection/type';
import Upload from '@/components/Upload/index.vue';
import batchAdd from './batchAdd.vue';
import { process_get, process_update } from '@/api/process';
import { JobStep } from './Selection/Step';
import { CheckCircleOutlined } from '@ant-design/icons-vue';
import useDrag from '@/views/Selection/Result/useDrag';

const removeArr = <T,>(list: T[], cb: (item: T) => boolean) => {
  const idx = list.findIndex(item => cb(item));
  if (idx > -1) {
    list.splice(idx, 1);
  }
};

const batchRef = ref<InstanceType<typeof batchAdd>>();
const rootRef = ref<HTMLElement>();

const node = st.get('_category') as Category;
const { categoryCode, categoryName, categoryPath, id: categoryId } = node;

const conditionColumns = ref([
  {
    title: '条件名称',
    dataIndex: 'alias_name',
  },
  {
    title: '操作',
    dataIndex: 'action',
    width: 300,
  },
]);

type ConditionItem = MatchData['conditions'][number];

const editValue = ref('');
const inputRef = ref<HTMLInputElement>();

const activeCondition = ref<ConditionItem>();

const conditionData = ref<ConditionItem[]>([]);

const conditionMap = computed(() => {
  const map: Map<string, ConditionItem> = new Map();
  conditionData.value.forEach(item => {
    map.set(item.alias_name!, item);
  });
  return map;
});

const batchOptionAdd = () => {
  batchRef.value?.show(list => {
    const repeatList: string[] = [];
    const _list = list.slice();
    const _key = activeCondition.value?.alias_name;
    if (_key) {
      while (_list.length) {
        const alias_name = _list.pop()!;
        if (optionMap.value[_key].has(alias_name)) {
          repeatList.unshift(alias_name);
          continue;
        }
        optionData.value[_key].unshift({
          option_name: generateUUID(),
          matches: [],
          alias_name,
          image_url: '',
        });
      }
    }
    if (repeatList.length) {
      message.warn(`选项${repeatList.join(',')}已存在,本次添加已跳过`);
    }
    return true;
  });
};

const swap = <T,>(arr: T[], i: number, j: number) => {
  const temp = arr[i];
  arr.splice(i, 1);
  arr.splice(j, 0, temp);
};

const customRow = useDrag(
  'condition',
  (i, j) => {
    swap(conditionData.value, i, j);
  },
  record => ({
    class:
      activeCondition.value?.alias_name == record.alias_name && 'row-active',
  }),
).customRow;

const optionCustomRow = (key: string) => {
  return useDrag(key, (i, j) => {
    swap(optionData.value[key], i, j);
  });
};

// 删除条件
const removeCondition = (record: ConditionItem, effect = true) => {
  removeArr(conditionData.value, item => item.alias_name == record.alias_name);
  effect &&
    removeArr(
      conditionSelects.value,
      item => item.alias_name == record.alias_name,
    );
  delete optionData.value[record.alias_name!];

  if (activeCondition.value?.alias_name == record.alias_name) {
    activeCondition.value = undefined;
    optionSelects.value = [];
  }
};

// 编辑条件
const editConddtion = (record: ConditionItem) => {
  if (conditionData.value.some(item => item.isEdit)) return;
  editValue.value = record.alias_name!;
  record.isEdit = true;

  nextTick(() => {
    inputRef.value?.focus();
  });
};

const saveCondition = (record: ConditionItem) => {
  if (!editValue.value) {
    if (record.alias_name) {
      record.isEdit = false;
      return;
    }
    const idx = conditionData.value.findIndex(
      item => item.alias_name == editValue.value,
    );
    if (idx > -1) {
      conditionData.value.splice(idx, 1);
      return;
    }
  }
  if (
    !conditionMap.value.has(editValue.value) ||
    record.alias_name == editValue.value
  ) {
    record.alias_name = editValue.value;
    record.isEdit = false;
    editValue.value = '';
    return;
  }

  message.destroy();
  message.warning(`条件${editValue.value}已存在,`);
  nextTick(() => {
    inputRef.value?.focus();
  });
};

const changeActive = (record: ConditionItem) => {
  if (activeCondition.value?.alias_name == record.alias_name) return;
  optionSelects.value = [];
  activeCondition.value = record;
  if (!optionData.value[record.alias_name!]) {
    optionData.value[record.alias_name!] = [];
  }
};

const optionsColumns = ref([
  {
    title: '选项',
    dataIndex: 'alias_name',
  },
  {
    title: '图片',
    dataIndex: 'icon',
  },
  {
    title: '操作',
    dataIndex: 'action',
    width: 200,
  },
]);

type OptionItem = ConditionOption;
const optionData = ref<Record<string, OptionItem[]>>({});
const optionMap = computed(() => {
  const record: Record<string, Map<string, OptionItem>> = {};
  Object.entries(optionData.value).forEach(item => {
    const map: Map<string, OptionItem> = new Map();
    const [key, options] = item;
    options.forEach(option => {
      map.set(option.alias_name, option);
    });
    record[key] = map;
  });
  return record;
});

const saveOption = (record: OptionItem) => {
  const _key = activeCondition.value!.alias_name!;
  const editList = optionData.value[_key];
  if (!editValue.value) {
    if (record.alias_name) {
      record.isEdit = false;
      return;
    }

    const idx = editList.findIndex(item => item.alias_name == editValue.value);
    if (idx > -1) {
      editList.splice(idx, 1);
      return;
    }
  }

  if (
    !optionMap.value[_key].has(editValue.value) ||
    record.alias_name == editValue.value
  ) {
    record.alias_name = editValue.value;
    record.isEdit = false;
    editValue.value = '';
    return;
  }
  message.destroy();
  message.warning(`选项${editValue.value}已存在`);

  nextTick(() => {
    inputRef.value?.focus();
  });
};

// 添加条件
const addCondition = () => {
  conditionData.value.unshift({
    alias_name: '',
    condition_name: generateUUID(),
    matches: [],
    isEdit: true,
  });
  nextTick(() => {
    inputRef.value?.focus();
  });
};

// 多选
const conditionSelects = ref<ConditionItem[]>([]);
const changeConditionSelect = (_, rows) => {
  conditionSelects.value = rows;
};

// 批量删除
const batchRemove = () => {
  conditionSelects.value.forEach(item => {
    removeCondition(item, false);
  });
  conditionSelects.value = [];
};

// 添加选项
const addOption = () => {
  const _key = activeCondition.value?.alias_name;
  if (_key) {
    optionData.value[_key].unshift({
      option_name: generateUUID(),
      matches: [],
      alias_name: '',
      isEdit: true,
    });

    nextTick(() => {
      inputRef.value?.focus();
    });
  }
};

// 编辑选项
const editOption = (record: OptionItem) => {
  const _key = activeCondition.value?.alias_name;
  if (_key) {
    const list = optionData.value[_key];
    if (list.some(item => item.isEdit)) return;
    editValue.value = record.alias_name!;
    record.isEdit = true;

    nextTick(() => {
      inputRef.value?.focus();
    });
  }
};

const optionSelects = ref<OptionItem[]>([]);
const changeOptionSelect = (_, selects) => {
  optionSelects.value = selects;
};

// 批量删除选项
const batchRemoveOptions = () => {
  optionSelects.value.forEach(item => {
    removeOption(item, false);
  });
  optionSelects.value = [];
};

// 删除选项
const removeOption = (record: OptionItem, effect = true) => {
  const _key = activeCondition.value?.alias_name;
  if (_key) {
    const editList = optionData.value[_key];
    removeArr(editList, item => item.alias_name == record.alias_name);
    effect &&
      removeArr(
        optionSelects.value,
        item => item.alias_name == record.alias_name,
      );
  }
};

// 批量添加条件
const showConditionBatch = () => {
  batchRef.value?.show(list => {
    const _list = list.slice();
    const repeatList: string[] = [];
    while (_list.length) {
      const alias_name = _list.pop()!;
      if (conditionMap.value.has(alias_name)) {
        repeatList.unshift(alias_name);
        continue;
      }
      conditionData.value.unshift({
        alias_name,
        condition_name: generateUUID(),
        matches: [],
        isEdit: false,
      });
    }

    if (repeatList.length) {
      message.warn(`条件${repeatList.join(',')}已存在,本次添加已跳过`);
    }
    return true;
  });
};

const { height } = useElementSize(rootRef);

const genProcessData = () => {
  let dummy = new JobStep();
  dummy.addNext(
    new JobStep('START', {
      ...startData.value,
      type: 'CUSTOM',
    }),
  );
  dummy.addNext(
    new JobStep('CONDITION_RELATION', {
      conditions: conditionData.value,
    }),
  );
  dummy.addNext(
    new JobStep('OPTION_RELATION', {
      conditions: conditionData.value.map(item => {
        return {
          alias_name: item.alias_name,
          condition_name: item.condition_name,
          options: optionData.value[item.alias_name!] || [],
        };
      }),
    }),
  );
  dummy.addNext(new JobStep('RESULT_ADJUST', {}));
  const data = dummy.next;

  return data!.format();
};

const router = useRouter();

const saveDsiable = computed(() => {
  if (!conditionData.value.length) return true;
  if (
    conditionData.value.some(
      item => !optionData.value[item.alias_name!]?.length,
    )
  )
    return true;
  return false;
});
const save = async () => {
  const res = await process_update({
    cid: categoryId,
    jobStep: 'RESULT_ADJUST',
    data: genProcessData(),
  });

  useRes(res, () => {
    message.success('操作成功');
    router.push({
      path: '/category',
    });
  });
};

const startData = ref({
  hancode_category: node,
  mapping_categories: [],
});
onMounted(() => {
  process_get(categoryId).then(res => {
    useRes(
      res,
      () => {
        console.log('编辑');
        const jobs = parseJson(res.data[0].data, []);
        startData.value = jobs[0].data;
        conditionData.value = jobs[1].data.conditions;
        optionData.value = jobs[2].data.conditions.reduce((res, item) => {
          res[item.alias_name] = item.options;
          return res;
        }, {});
        if (conditionData.value.length) {
          activeCondition.value = conditionData.value[0];
        }
      },
      () => {
        console.log('新建');
      },
    );
  });
});
</script>
